using System;
using System.Drawing;

using SdlDotNet.Graphics;
using SdlDotNet.Graphics.Sprites;

using Game.Data;
using Game.Utils;

namespace Game.Output
{
	public static class CConsole
	{
		public enum ID
		{
			HEADER	= 0,
			PROCESS	= 1,
			STATUS	= 2,
			PARAM	= 3,
			SUCCESS	= 4,
			ERROR	= 5,
			CHATMSG	= 6
		}
		
		private const int	LINES_AMOUNT	= 10;
		private const int	FONT_SIZE		= 12;
		private const int	LINE_HEIGHT		= 14;
		
		private static Surface	m_surface;		
		private static Point	m_position;
		private static bool		m_ingameConsoleInitialized = false;
		
		private static SdlDotNet.Graphics.Font	m_font;
		private static TextSprite[]				m_textSprites;
		private static int						m_lineNr;
		
		public static void Initialize()
		{
			CConsole.ReportClassInit(System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.Name);
			
			Console.SetWindowSize(80,40);
			
			Console.BufferHeight	= 1000;
			Console.BufferWidth		= 100;
			Console.Title			= CData.Texts.Get("GAME_TITLE");
		}

		public static void ReportClassInit(string p_name)
		{
			WriteLineToSystemConsole(ID.HEADER, "" + p_name);
		}
		
		public static void ReportParam(string p_name, string p_value)
		{
			WriteLineToSystemConsole(ID.PARAM, "" + p_name + " = " + p_value);
		}
		
		public static void ReportProcess(string p_text)
		{
			WriteLineToSystemConsole(ID.PROCESS, p_text);
		}
		
		public static void ReportStatus(string p_text)
		{
			WriteLineToSystemConsole(ID.STATUS, p_text);
		}
		
		public static void ReportChat(int p_playerNr, string p_text)
		{
			WriteLineToSystemConsole(ID.CHATMSG, p_text);
		}
		
		public static void WriteLineToSystemConsole(ID p_id, string p_text)
		{
			string text = "";
			
			switch (p_id)
			{
				case ID.HEADER :
					text = "" + p_text;
					Console.ForegroundColor = ConsoleColor.White;
					break;
					
				case ID.PROCESS :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Gray;
					break;
					
				case ID.STATUS :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Gray;
					break;
					
				case ID.PARAM :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Gray;
					break;
					
				case ID.ERROR :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Red;
					break;
					
				case ID.SUCCESS :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Green;
					break;
				
				case ID.CHATMSG :
					text = "\t" + p_text;
					Console.ForegroundColor = ConsoleColor.Gray;
					break;
					
				default : // case 0
					throw new Exception("No valid priority!");
			}
			
			WriteToSystemConsole(text + "\n");
		}
		
		public static void WriteToSystemConsole(string p_text)
		{
			Console.Write(p_text);
			// and log ...
		}
		
		public static void InitializeIngameConsole()
		{
			CConsole.ReportClassInit(System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.Name);
			
			CSurfaceFactory.CreateSurface(out m_surface, new Size(300, 300));
			
			m_position = new Point(0,0);
			               
			m_font =
				new SdlDotNet.Graphics.Font(CData.Paths.Get("FONTS") + @"arial.ttf", FONT_SIZE);
			m_textSprites =
				new TextSprite[LINES_AMOUNT];
			m_lineNr = 0;
			
			for (int i = 0; i < LINES_AMOUNT; i++)
			{
				m_textSprites[i] = new TextSprite("", m_font, Color.White, true);		
			}
			
			m_ingameConsoleInitialized = true;
		}
		
		public static void WriteToIngameConsole(Color p_color, string p_text)
		{
			m_textSprites[LINES_AMOUNT - 1].Text =
				m_textSprites[LINES_AMOUNT - 1].Text + p_text;
		}
		
		public static void WriteLineToIngameConsole(Color p_color, string p_text)
		{
			if (++m_lineNr >= LINES_AMOUNT)
				m_lineNr = 0;
			
			for (int i = 0; i < LINES_AMOUNT - 1; i++)
			{
				m_textSprites[i].Text = m_textSprites[i + 1].Text;	
			}
			
			m_textSprites[LINES_AMOUNT - 1].Text = p_text;
		}
		
		public static void Render(ref Surface p_surface)
		{
			if (!m_ingameConsoleInitialized)
				return;
			
			for (int i=0; i<LINES_AMOUNT; i++)
			{
				m_surface.Blit(m_textSprites[i], new Point(0, 0 + i * LINE_HEIGHT));		
			}
		}			
	}
}
